package com.ec.auth.security.filter;

import java.io.IOException;
import javax.security.sasl.AuthenticationException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import com.ec.common.core.domain.model.LoginUser;
import com.ec.common.utils.SecurityUtils;
import com.ec.common.utils.StringUtils;
import com.ec.auth.web.service.TokenService;

/**
 * token过滤器 验证token有效性
 * 这是一个自定义的过滤器类，扩展了OncePerRequestFilter。
 * 过滤器用于处理 HTTP 请求并执行一些认证逻辑
 * @author ec
 */
@Component//  Spring 的注解，用于将该类标记为 Spring 管理的组件
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    @Autowired
    private TokenService tokenService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        // 这行代码从TokenService获取与当前请求相关的登录用户信息
        LoginUser loginUser = tokenService.getLoginUser(request);
        // 这是一个条件判断，检查登录用户是否不为空，并且当前的安全认证信息是否为空
        if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) {
            // 这行代码获取请求头中的"tenant"字段的值 就是租户id
            String tenant = request.getHeader("tenant");
            // 检查登录用户对象的租户id是否与请求头中的租户信息匹配
            if (!loginUser.getTenant().equalsIgnoreCase(tenant)) {
                throw new AuthenticationException("令牌无效");
            }
            /**
             *      String tenant = request.getHeader("tenant");
             *
             *         if (StringUtils.isEmpty(tenant)) {
             *             return AjaxResult.error("租户ID不能为空");
             *         }
             */

            // 令牌有效后 看看令牌的有效时间
            tokenService.verifyToken(loginUser);
            // 这是创建一个新的UsernamePasswordAuthenticationToken对象，其中包含登录用户的信息和权限
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
            // 这行代码设置认证令牌的详细信息，可能与请求的相关信息有关
            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            // 这行代码将认证令牌设置到安全上下文持有者中，以便后续的请求可以访问到认证信息
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }
        // 这行代码将请求传递给下一个过滤器或目标处理程序进行处理
        chain.doFilter(request, response);
    }
}
